package room_event

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/spf113/cast"
	"longmen/server/config/global"
	"longmen/server/internal/rpc/tencentim/chat"
	"longmen/server/internal/rpc/tencentim/imsdk"
	messages2 "longmen/server/internal/rpc/tencentim/messages"
	"longmen/server/pkg/common/helper/timehelper"
	"longmen/server/pkg/db/mysql/db_live"
	"longmen/server/pkg/db/mysql/db_main"
	"longmen/server/pkg/db/redis/cache"
)

const (
	chatHistoryStartIndex = 0      // 第一条从0开始
	chatHistoryLimit      = 30 - 1 // 历史聊天记录限制条数
	lengthLimit           = 5000   //20条消息的总长度(包装的结构大概有200字，100字留给内容，道具的话内容会x2)
)

type chatHistory struct {
	id int // 房间ID
}

func GetChatHistory(roomId int) *chatHistory {
	return &chatHistory{
		roomId,
	}
}

func (r *chatHistory) AppendChatHistory(content interface{}) {
	key := cache.GenChatHistoryRoom(r.id)
	bytes, _ := json.Marshal(content)
	rds := global.GetRds()
	_, err := rds.LPush(key, string(bytes)).Result()
	if err != nil {
		global.Log.Errorf("room[%d]: push msg error: %v", r.id, err)
		return
	}
	count := rds.LLen(key).Val()
	if count >= chatHistoryLimit {
		rds.LTrim(key, chatHistoryStartIndex, chatHistoryLimit)
	}
}

func (r *chatHistory) GetChatHistory() []map[string]interface{} {
	records := make([]map[string]interface{}, 0)
	rds := global.GetRds()
	result, err := rds.LRange(cache.GenChatHistoryRoom(r.id), chatHistoryStartIndex, chatHistoryLimit).Result()
	if err != nil {
		global.Log.Errorf("history:%v", err)
		return records
	}
	if len(result) == 0 {
		return records
	}
	nSize := lengthLimit
	iTail := len(result) - 1
	for s := 0; s < len(result); s++ {
		if nSize-len(result[s]) < 0 { //长度够了啊
			iTail = s
			break
		}
		nSize -= len(result[s])

	}
	for s := iTail; s >= 0; s-- {
		tempMap := make(map[string]interface{})
		err := json.Unmarshal([]byte(result[s]), &tempMap)
		if err != nil {
			continue
		}
		records = append(records, tempMap)
	}

	//global.Log.Infof("hisRecords:%v", records)
	return records
}

//删除指定聊天记录
func (r *chatHistory) DeleteChatHistory(id int64, op string) error {
	rds := global.GetRds()
	key := cache.GenChatHistoryRoom(r.id)
	result, err := rds.LRange(key, chatHistoryStartIndex, chatHistoryLimit).Result()
	if err != nil {
		global.Log.Errorf("get chathistory error: %v", err)
		return err
	}
	switch op {
	case messages2.ClearHisChatType:
		for _, str := range result {
			his := messages2.ChatHistory{}
			err := json.Unmarshal([]byte(str), &his)
			if err != nil {
				continue
			}
			if his.Id == id {
				rds.LRem(key, 1, str)
			}
		}
	case messages2.ClearHisCloseType:
		rds.Del(key)
	}
	return nil
}

//同步处理禁言用户 这里处理的后台来的请求
func BanUserAllChanSync(req *messages2.BanUserChatReq) error {
	global.Log.Debugf("banUser收到admin禁言 請求 %+v: ", req)
	return doDealBanUser(req)
}

//前台（主播或房管）在群组里禁言用户
func BanUserGroup(req *messages2.BanUserChatReq) error {
	global.Log.Debugf("banUser收到前台禁言 請求 %+v: ", req)
	return doDealBanUser(req)
}

func doDealBanUser(req *messages2.BanUserChatReq) error {
	if req.BanType == messages2.BanUserType {
		rspMsg := genBannedMsg(req.NickName, req.Reason, req.TBan)
		go setNoSpeaking(int64(req.UserId), req.NickName, rspMsg, req.TBan)
		return nil

	} else {
		iRoomId := req.RoomId
		if iRoomId == 0 {
			user := chat.GetClientUser(req.UserId)
			if user == nil {
				global.Log.Warn("group ban failed, 群组id不能为0")
				return errors.New("group ban failed, 群组id不能为0")
			} else {
				iRoomId = user.RoomId
			}
		}
		setCanSpeaking(iRoomId, int64(req.UserId), req.NickName)
	}

	return nil
}

func setNoSpeaking(uid int64, nickName, msg string, durationBan int64) error {
	banType := messages2.RoomUserBannedMessageType
	lives, err := db_live.GetLivesAll()
	if err != nil {
		return err
	}
	rds := global.GetRds()
	for _, live := range lives {
		key := cache.GenChatHistoryRoom(live.Anchorid)
		result, err := rds.LRange(key, chatHistoryStartIndex, chatHistoryLimit).Result()
		if err != nil {
			continue
		}
		for _, str := range result {
			his := messages2.ChatHistory{}
			err := json.Unmarshal([]byte(str), &his)
			if err != nil {
				continue
			}
			if his.UserId == uid {
				rds.LRem(key, 1, str)
				imsdk.GetSdk().BroadcastInterface(live.Anchorid, &messages2.RoomBanUserMessage{
					SentMessageStruct: messages2.SentMessageStruct{Type: banType},
					UserId:            int(uid),
					ClientName:        nickName,
					Message:           msg,
				}, 3)

			}
		}
	}
	db_main.DeleteEsChatHistoryByRoomIdUserId(int(uid)) //去es里给他删消息
	err = imsdk.GetSdk().GlobalForbidMsg(cast.ToString(uid), true, durationBan)
	return err
}

func setCanSpeaking(roomId int, uid int64, nickName string) error {
	rspMsg := fmt.Sprintf("【%s】%s", nickName, global.Lang.T("unmute"))
	banType := messages2.UnbanUserMessageType
	imsdk.GetSdk().GlobalForbidMsg(cast.ToString(uid), true, 0)
	err := imsdk.GetSdk().BroadcastInterface(roomId, &messages2.RoomBanUserMessage{
		SentMessageStruct: messages2.SentMessageStruct{Type: banType},
		UserId:            int(uid),
		ClientName:        nickName,
		Message:           rspMsg,
	}, 3)
	return err
}

//清除聊天记录
func ClearChat(c *messages2.ClearMessage) error {
	m := &messages2.ClearChatMessage{
		SentMessageStruct: messages2.SentMessageStruct{Type: messages2.RoomClearChatType},
		RoomId:            c.RoomId,
		ChatId:            c.ChatId,
		UserId:            c.UserId,
	}
	err := imsdk.GetSdk().BroadcastInterface(c.RoomId, m, 3)
	db_main.DeleteEsChatHistoryById(c.RoomId, c.ChatId)
	err = GetChatHistory(c.RoomId).DeleteChatHistory(int64(c.ChatId), messages2.ClearHisChatType)
	if err != nil {
		global.Log.Errorf("clear redis error:%s", err.Error())
		return err
	}
	global.Log.Debugf("clear:%+v", m)
	return nil
}

func genBannedMsg(sNickname, sReason string, tBan int64) (msg string) {
	msg = ""
	if len(sReason) > 0 {
		msg = msg + fmt.Sprintf("%s【%s】", global.Lang.T("due_to"), sReason)
	}
	msg = msg + fmt.Sprintf("%s%s。", global.Lang.T("restricted_from_speaking"), timehelper.Time2Msg(tBan))
	return
}
